#ifndef __FD_CONTEXT_H__
#define __FD_CONTEXT_H__

#include <memory>
#include <map>

enum CoFdType
{
    CO_FD_FILE   = 0,
    CO_FD_SOCKET = 1,
};

enum CoFdEventType
{
    CO_FD_IN  = 0x1, 
    CO_FD_OUT = 0x2, 
};

enum CoFdTimeoutType
{
    CO_FD_WRITE_TIMEOUT   = 0x01, 
    CO_FD_READ_TIMEOUT    = 0X02,
    CO_FD_CONNECT_TIMEOUT = 0X04,
};

class CoFdContext;
class CoSocketContext;

typedef std::shared_ptr<CoFdContext>     CoFdContextPtr;
typedef std::shared_ptr<CoSocketContext> CoSocketContextPtr;

class CoFdContext
{
friend class CoFdReactor;
public:
    CoFdContext(int fd, CoFdType type);

    virtual ~CoFdContext();

    int get_fd();

    CoFdType get_type();

    bool is_block();

    void set_block_flag(bool block);

    void set_timeout(CoFdTimeoutType type, int msec);

    int get_timeout(CoFdTimeoutType type);

    virtual CoFdContextPtr clone(int fd);

private:
    void set_events(int events);

    int get_events();

    void reset_events();

public:
    int         _fd;
    CoFdType    _type;
    bool        _is_block;

    int         _events;

    std::map<CoFdTimeoutType, int> _timeouts;   // 单位：毫秒
};

struct CoSocketAttribute
{
    int domain;
    int type;
    int protocol;
};

class CoSocketContext : public CoFdContext
{
public:
    CoSocketContext(int fd, CoFdType type, CoSocketAttribute attr);

    CoFdContextPtr clone(int fd);

    CoSocketAttribute get_attr();

private:
    CoSocketAttribute _attr;
};

#endif

